#include "TimeHelper.h" 
#include "math.h"
#include "time.h"


time_t TimeHelper::GetMondayTime(time_t Time)
{
	//struct tm {
	//	int tm_sec; /* 秒 – 取值区间为[0,59] */
	//	int tm_min; /* 分 - 取值区间为[0,59] */
	//	int tm_hour; /* 时 - 取值区间为[0,23] */
	//	int tm_mday; /* 一个月中的日期 - 取值区间为[1,31] */
	//	int tm_mon; /* 月份（从一月开始，0代表一月） - 取值区间为[0,11] */
	//	int tm_year; /* 年份，其值等于实际年份减去1900 */
	//	int tm_wday; /* 星期 – 取值区间为[0,6]，其中0代表星期天，1代表星期一，以此类推 */
	//	int tm_yday; /* 从每年的1月1日开始的天数 – 取值区间为[0,365]，其中0代表1月1日，1代表1月2日，以此类推 */
	//	int tm_isdst; /* 夏令时标识符，实行夏令时的时候，tm_isdst为正。不实行夏令时的进候，tm_isdst为0；不了解情况时，tm_isdst()为负。*/
	//};
	struct tm local;
	_localtime64_s(&local ,&Time);

	int weekday;//星期几
	if (local.tm_wday == 0)//星期日
		weekday = 7;
	else
		weekday = local.tm_wday;

	return Time - (weekday - 1) * 86400;//获取该周的周1时间戳
}

FString TimeHelper::GetWeekRange(time_t Time)
{
	
	struct tm local;
	FString WeekRange;
	_localtime64_s(&local ,&Time);

	//int weekday;//星期几
	//if(local.tm_wday == 0)//星期日
	//	weekday = 7;
	//else
	//	weekday = local.tm_wday;

	Time = Time - (local.tm_wday - 1) * 86400;
	_localtime64_s(&local ,&Time);
	WeekRange.Append(FString::Format(TEXT("{0}年 {1}.{2}-"), { local.tm_year + 1900,local.tm_mon + 1,local.tm_mday}));
	Time = Time + 86400 * 6;
	_localtime64_s(&local ,&Time);
	WeekRange.Append(FString::Format(TEXT("{0}.{1}"), {local.tm_mon + 1,local.tm_mday }));
	return WeekRange;
}


FString TimeHelper::UnixTimestampToStr(time_t Time)//时间戳转字符串
{
	struct tm local;
	_localtime64_s(&local, &Time);
	return FString::Format(TEXT("{0}-{1}-{2}"), { local.tm_year + 1900,local.tm_mon + 1,local.tm_mday });
}

int TimeHelper::DaysSub(time_t day1, time_t day2)//两个时间的减法会返回负数
{
	//此函数是为了解决一个尴尬的问题,例如 2020.1.1 23:59:59 和 2020.1.2 0:0:0  两者只相差1秒 但是天数却相差了1天.如果单纯的通过时间戳之间的差值来判断,则认为两者间相差0天
	struct tm local1;
	struct tm local2;
	_localtime64_s(&local1, &day1);
	_localtime64_s(&local2, &day2);
	//	int tm_sec; /* 秒 – 取值区间为[0,59] */
//	int tm_min; /* 分 - 取值区间为[0,59] */
//	int tm_hour; /* 时 - 取值区间为[0,23] */
	local1.tm_sec = local1.tm_min = local1.tm_hour = 0;
	local2.tm_sec = local2.tm_min = local2.tm_hour = 0;

	time_t newday1 = mktime(&local1);
	time_t newday2 = mktime(&local2);

	return (newday2 - newday1) / ONE_DAY_SECOND;
}

int TimeHelper::GetYear(time_t time)
{
	struct tm local;
	_localtime64_s(&local, &time);
	return local.tm_year + 1900;
}

int TimeHelper::GetMonth(time_t time)
{
	struct tm local;
	_localtime64_s(&local, &time);
	return local.tm_mon + 1;
}

int TimeHelper::GetDay(time_t time)
{
	struct tm local;
	_localtime64_s(&local, &time);
	return local.tm_mday;
}

uint16 TimeHelper::DaysBetween2Date(time_t day1, time_t day2)
{
	//此函数是为了解决一个尴尬的问题,例如 2020.1.1 23:59:59 和 2020.1.2 0:0:0  两者只相差1秒 但是天数却相差了1天.如果单纯的通过时间戳之间的差值来判断,则认为两者间相差0天
	struct tm local1;
	struct tm local2;
	_localtime64_s(&local1, &day1);
	_localtime64_s(&local2, &day2);
	//	int tm_sec; /* 秒 – 取值区间为[0,59] */
//	int tm_min; /* 分 - 取值区间为[0,59] */
//	int tm_hour; /* 时 - 取值区间为[0,23] */
	local1.tm_sec = local1.tm_min = local1.tm_hour = 0;
	local2.tm_sec = local2.tm_min = local2.tm_hour = 0;

	time_t newday1 = mktime(&local1);
	time_t newday2 = mktime(&local2);

	return abs(newday1 - newday2) / ONE_DAY_SECOND;
}

bool TimeHelper::FloatEquality(float a, float b) {
	//由于FLOAT的特殊性这种写法就是判断FLOAT类型是否等于6.0
	return FMath::Abs(a - b) < 0.0001;
};

bool TimeHelper::FloatEqualityEx(float a, float b, int place)//判断小数点后N位的相等比较
{
	if(place > 8)
	place = 8;
	int64 inta = (int64)(FMath::Pow(10,place) * a);
	int64 intb = (int64)(FMath::Pow(10, place) * b);
	return inta == intb;
}

uint16 TimeHelper::GetMonthDays(int year, int month)//获得一个月的天数
{
	int d;
	int day[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
	if (2 == month)
	{
		d = (((0 == year % 4) && (0 != year % 100) || (0 == year % 400)) ? 29 : 28);
	}
	else
	{
		d = day[month - 1];
	}
	return d;
}

uint16 TimeHelper::GetFirstDayWeekForMonth(int year, int month, int day)//利用泰勒公式获得一个日期是星期几
{

	if (month == 1 || month == 2)//判断month是否为1或2　
	{
		year--;
		month += 12;
	}
	int c = year / 100;
	int y = year - c * 100;
	int week = y + y / 4 + c / 4 - 2 * c + 26 * (month + 1) / 10 + day - 1;//泰勒公式
	while (week < 0)
		week += 7;
	week %= 7;
	//week ==0 则代表周末
	if (week == 0)
		return 7;
	else
		return week;
}

bool TimeHelper::StrDateToTImestamp(FString time,int &year,int &month,int &day)//通过字符串yyyy-mm-dd获得时间戳
{

	TArray<FString> stringArray;
	time.ParseIntoArray(stringArray, TEXT("-"), false);
	if (stringArray.Num() == 3)
	{
		year = atoi((TCHAR_TO_UTF8(*stringArray[0])));
		month = atoi((TCHAR_TO_UTF8(*stringArray[1])));
		day = atoi((TCHAR_TO_UTF8(*stringArray[2])));
		if(year < 2000 || year > 3000)
		return false;
		if(month < 1 || month > 12)
		return false;
		if(day < 1 || day > 31)
		return false;
		return true;
	}
	return false;
}

time_t  TimeHelper::DateToTimestamp(int Inyear, int Inmonth, int Inday)//通过日期获得时间戳
{
	struct tm tt;
	memset(&tt, 0, sizeof(tt));
	tt.tm_year = Inyear - 1900;
	tt.tm_mon = Inmonth - 1;
	tt.tm_mday = Inday;
	tt.tm_hour = 0;
	tt.tm_min = 0;
	tt.tm_sec = 0;
	return mktime(&tt);
}

time_t TimeHelper::GetTodayZero()
{
	int32 Year, Month, Day, DayOfWeek;
	int32 Hour, Minute, Second, Millisecond;

	FPlatformTime::SystemTime(Year, Month, DayOfWeek, Day, Hour, Minute, Second, Millisecond);

	struct tm tt;
	memset(&tt, 0, sizeof(tt));
	tt.tm_year = Year - 1900;
	tt.tm_mon = Month - 1;
	tt.tm_mday = Day;
	tt.tm_hour = 0;
	tt.tm_min = 0;
	tt.tm_sec = 0;
	return mktime(&tt);
}



//int TimeHelper::GetYear(time_t time)
//{
//	struct tm local;
//	_localtime64_s(&local, &time);
//	return local.tm_year + 1900;
//}
//
//int TimeHelper::GetMonth(time_t time)
//{
//	struct tm local;
//	_localtime64_s(&local, &time);
//	return local.tm_mon + 1;
//}
//
//int TimeHelper::GetDay(time_t time)
//{
//	struct tm local;
//	_localtime64_s(&local, &time);
//	return local.tm_mday;
//}

time_t TimeHelper::Get00_00_00ToTimestamp(time_t Time)//给定一个时间戳,返回这一天的0点0分0秒的时间戳
{
	struct tm local1;
	_localtime64_s(&local1, &Time);
	local1.tm_hour = 0;
	local1.tm_min = 0;
	local1.tm_sec = 0;
	time_t newtime = mktime(&local1);
	return newtime;
}

void TimeHelper::GetDayAdd(time_t time, int num, int& year, int& month, int& day)//给日期做加法
{
	time += num * ONE_DAY_SECOND;
	struct tm local1;
	_localtime64_s(&local1, &time);
	year = local1.tm_year + 1900;
	month = local1.tm_mon + 1;
	day = local1.tm_mday;
}

void TimeHelper::TimestampToData(time_t Time, int& year, int& month, int& day)//时间戳转年月日
{
	struct tm local1;
	_localtime64_s(&local1, &Time);
	year = local1.tm_year + 1900;
	month = local1.tm_mon + 1;
	day = local1.tm_mday;
}